/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package synchronization;

import Repository.IRepositoryProxy;
import SynchronizationLayer.Conversation;
import SynchronizationLayer.ConversationGroup;
import SynchronizationLayer.ISynchronizationServer;
import SynchronizationLayer.NotarySynchronizationMessage;
import SynchronizationLayer.NotarySynchronizationMessageType;
import SynchronizationLayer.NotarySynchronizationPacket;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.security.InvalidParameterException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Tomasz Nowak
 */
class SynchronizationServerReceiver implements Runnable
{
	DatagramSocket socket;
	IRepositoryProxy repositoryProxy;
	ConversationGroup[] conversationGroups;
	ISynchronizationServer SynchronizationServer;

	public SynchronizationServerReceiver( DatagramSocket socket, IRepositoryProxy repositoryProxy, ConversationGroup[] conversationGroups, ISynchronizationServer synchronizationServer )
	{
		this.socket = socket;
		this.repositoryProxy = repositoryProxy;
		this.conversationGroups = conversationGroups;
		this.SynchronizationServer = synchronizationServer;
	}

	@Override
	public void run()
	{
		while ( true )
		{
			try
			{
				byte[] packetLenghtArray = new byte[2];

				DatagramPacket packet = new DatagramPacket(packetLenghtArray, packetLenghtArray.length);
				socket.receive(packet);

				int packetlength = ( int ) packet.getData()[1] + ( int ) packet.getData()[0] * 256;

				byte[] packetArray = new byte[packetlength];
				packet = new DatagramPacket(packetArray, packetArray.length);
				socket.receive(packet);

				ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(packet.getData());

				ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
				NotarySynchronizationPacket receivedPacket = new NotarySynchronizationPacket(
								( NotarySynchronizationMessage ) objectInputStream.readObject(),
								packet.getAddress(), packet.getPort());

				ConversationGroup group = getConversationGroup(
								receivedPacket.getNotarySynchronizationMessage().getNotarySynchronizationMessageType());

				Conversation conversation = group.getConversation(receivedPacket);

				if ( conversation != null )
				{
					conversation.receivePacket(receivedPacket, repositoryProxy, SynchronizationServer);
				}
			}
			catch ( IOException ex )
			{
				Logger.getLogger(SynchronizationServer.class.getName()).log(Level.SEVERE, null, ex);
			}
			catch ( ClassNotFoundException ex )
			{
				Logger.getLogger(SynchronizationServer.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
	}

	ConversationGroup getConversationGroup( NotarySynchronizationMessageType type )
	{
		for ( ConversationGroup conversationGroup: conversationGroups )
		{
			for ( NotarySynchronizationMessageType notarySynchronizationMessageType: conversationGroup.getMessageTypes() )
			{
				if ( type.equals(notarySynchronizationMessageType) )
				{
					return conversationGroup;
				}
			}
		}
		throw new InvalidParameterException("NotarySynchronizationMessageType");
	}
}
